package com.lmx.common.util;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;

import com.lmx.repoDomain.tmodel.Dicttype;
import com.lmx.repoDomain.tmodel.unpersis.POIParam;

/**
 * excel导出工具类
 * 
 * @author ytche
 * @date 2017年5月8日
 * 
 */
public class ExcelExport<T> {
	private Log logger = LogFactory.getLog(this.getClass());
	private final String path;
	private final String title;

	/**
	 * @param path导出文件路径
	 * @param title导出文件内工作簿的名称
	 */
	public ExcelExport(String path, String title) {
		this.path = path;
		this.title = title;
	}

	/**
	 * 单工作表导出
	 * 
	 * @author ytche
	 * @param dataList导出数据
	 * @param params导出参数
	 * @date 2017年5月8日 下午2:58:20
	 */
	public void export(List<T> dataList, List<POIParam> params) {
		HSSFWorkbook workbook = new HSSFWorkbook();
		HSSFSheet sheet = workbook.createSheet(this.title);
		sheet.setDefaultColumnWidth(15);
		HSSFCellStyle headerStyle = this.CreateHeaderStyle(workbook);
		HSSFCellStyle cellStyle = this.CreateDataStyle(workbook);
		this.createHeaderRow(params, sheet, headerStyle);
		this.fillDataRow(dataList, sheet, params, cellStyle);
		try {
			OutputStream out = new FileOutputStream(this.path);
			workbook.write(out);
			out.close();
		} catch (FileNotFoundException e) {
			logger.error("导出excel,导出文件夹不存在");
		} catch (IOException e) {
			logger.error("导出excel,IO异常");
		}

	}

	/**
	 * 填充数据列
	 * 
	 * @author ytche
	 * @param dataList
	 * @param sheet
	 * @param params
	 * @param cellStyle
	 * @date 2017年5月8日 上午11:14:02
	 */
	private void fillDataRow(List<T> dataList, HSSFSheet sheet,
			List<POIParam> params, HSSFCellStyle cellStyle) {
		Iterator<T> it = dataList.iterator();
		int index = 0;
		while (it.hasNext()) {
			// index++;
			HSSFRow row = sheet.createRow(++index);
			T entity = it.next();
			for (int colNum = 0; colNum < params.size(); colNum++) {
				HSSFCell cell = row.createCell(colNum);
				POIParam param = params.get(colNum);
				String colName = param.getColName();
				try {
					Object value = getFieldValue(entity, colName);
					this.setCellValue(cell, value, param);
				} catch (Exception e) {
					logger.error("excel导出错误", e);
				}
			}

		}

	}

	/**
	 * 获取字段值
	 * 
	 * @author ytche
	 * @param entity
	 * @param colName
	 * @return
	 * @date 2017年5月8日 下午3:00:58
	 */
	private Object getFieldValue(Object entity, String colName)
			throws Exception {
		Object value = null;
		Class entityClass = entity.getClass();

		if (colName.indexOf(".") < 0) {
			String getMethodName = new StringBuilder("get")
					.append(colName.substring(0, 1).toUpperCase())
					.append(colName.substring(1)).toString();
			Method getMethod = entityClass.getMethod(getMethodName,
					new Class[] {});
			value = getMethod.invoke(entity, new Object[] {});
		} else {
			String[] array = colName.split("\\.");
			String fieldName = array[0];
			String childFieldName = colName.substring(fieldName.length() + 1);
			String getMethodName = new StringBuilder("get")
					.append(fieldName.substring(0, 1).toUpperCase())
					.append(fieldName.substring(1)).toString();
			Method getMethod = entityClass.getMethod(getMethodName,
					new Class[] {});
			Object fieldValue = getMethod.invoke(entity, new Object[] {});
			value = this.getFieldValue(fieldValue, childFieldName);// 回调获取关联类的值
		}
		return value;
	}

	/**
	 * 填充数据单元格
	 * 
	 * @author ytche
	 * @param cell
	 * @param value
	 * @param class1
	 * @date 2017年5月5日 下午6:05:38
	 */
	private void setCellValue(HSSFCell cell, Object value, POIParam param) {
		String textValue = "";
		if (StringUtils.isNotBlank(param.getFormat())) {
			Long time = (long) (((Integer) value));
			time = time * 1000;
			Date date = new Date(time);
			DateFormat format = new SimpleDateFormat(param.getFormat());
			textValue = format.format(date);
		} else if (value instanceof Date) {
			String formatStr = StringUtils.isBlank(param.getFormat())
					? "yyyy-MM-dd" : param.getFormat();
			DateFormat format = new SimpleDateFormat(formatStr);
			textValue = format.format((Date) value);
		} else if (value instanceof Boolean) {
			textValue = (Boolean) value ? "是" : "否";
		} else if (value instanceof Dicttype) {
			textValue = ((Dicttype) value).getTypename();
		} else {
			textValue = value.toString();
		}
		if (!"".equals(textValue)) {
			if (textValue.matches("^//d+(//.//d+)?$")) {
				// 是数字当作double处理
				cell.setCellValue(Double.parseDouble(textValue));
			} else {
				HSSFRichTextString richString = new HSSFRichTextString(
						textValue);
				cell.setCellValue(richString);
			}
		}

	}

	/**
	 * 构建表头
	 * 
	 * @author ytche
	 * @param params
	 * @param sheet
	 * @param headerStyle
	 * @date 2017年5月5日 下午6:52:59
	 */
	private void createHeaderRow(List<POIParam> params, HSSFSheet sheet,
			HSSFCellStyle headerStyle) {
		HSSFRow row = sheet.createRow(0);
		for (int i = 0; i < params.size(); i++) {
			HSSFCell cell = row.createCell(i);
			cell.setCellStyle(headerStyle);
			HSSFRichTextString text = new HSSFRichTextString(
					params.get(i).getColTitle());
			cell.setCellValue(text);
		}
	}

	/**
	 * 设置表头样式
	 * 
	 * @author ytche
	 * @param workbook
	 * @return
	 * @date 2017年5月5日 下午3:54:08
	 */
	private HSSFCellStyle CreateHeaderStyle(HSSFWorkbook workbook) {
		HSSFCellStyle style = workbook.createCellStyle();
		style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

		HSSFFont font = workbook.createFont();
		font.setColor(HSSFColor.VIOLET.index);
		font.setFontHeightInPoints((short) 12);
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		style.setFont(font);
		return style;
	}

	/**
	 * 设置数据单元格样式
	 * 
	 * @author ytche
	 * @param workbook
	 * @return
	 * @date 2017年5月5日 下午3:54:23
	 */
	private HSSFCellStyle CreateDataStyle(HSSFWorkbook workbook) {
		HSSFCellStyle style = workbook.createCellStyle();
		style.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		// 生成另一个字体
		HSSFFont font2 = workbook.createFont();
		font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		// 把字体应用到当前的样式
		style.setFont(font2);
		return style;
	}
}
